package com.gitee.wsl.reflect

import kotlin.reflect.KClass
import kotlin.reflect.KType
import kotlin.reflect.typeOf


//public actual fun Any.instanceOf(type: KClass<*>): Boolean = type.isInstance(this)


/**
 * Check [this] is instance of [type].
 */
 expect fun Any.instanceOf(type: KClass<*>): Boolean


/**
 * Ktor type information.
 * @property type Source KClass<*>
 * @property kotlinType Kotlin reified type with all generic type parameters.
 */
 class TypeInfo(
     val type: KClass<*>,
     val kotlinType: KType? = null
) {

    override fun hashCode(): Int {
        return kotlinType?.hashCode() ?: type.hashCode()
    }

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (other !is TypeInfo) return false

        return if (kotlinType != null || other.kotlinType != null) {
            kotlinType == other.kotlinType
        } else {
            type == other.type
        }
    }

    override fun toString(): String = "TypeInfo(${kotlinType ?: type})"
}

inline fun <reified T : Any> TypeInfo.isType() = type == T::class

/**
 * Returns [TypeInfo] for the specified type [T]
 */
 inline fun <reified T> typeInfo(): TypeInfo = TypeInfo(T::class, typeOfOrNull<T>())

/**
 * Check [this] is instance of [type].
 */
// expect fun Any.instanceOf(type: KClass<*>): Boolean

@PublishedApi
internal inline fun <reified T> typeOfOrNull(): KType? = try {
    // We need to wrap getting a type in try catch because of:
    // - KT-42913
    // - KTOR-7479 (R8 in full mode strips class signatures)
    typeOf<T>()
} catch (_: Throwable) {
    null
}
